////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001-2004.
// -------------------------------------------------------------------------
//  File name:   MaterialBrowser.h
//  Version:     v1.00
//  Created:     26/8/2004 by Timur.
//  Compilers:   Visual Studio.NET 2003
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __MaterialBrowser_h__
#define __MaterialBrowser_h__
#pragma once

#include "Include\IDataBaseManager.h"
#include "ToolbarDialog.h"
#include "Controls\TreeCtrlReport.h"

struct IDataBaseItem;
struct IDataBaseManager;
class  CMaterial;

class CMaterialBrowserCtrl;
class CMaterialImageListCtrl;

//////////////////////////////////////////////////////////////////////////
// Item class for browser.
//////////////////////////////////////////////////////////////////////////
class CMaterialBrowserRecord : public CTreeItemRecord
{
public:
	CMaterialBrowserRecord() { pMaterial = 0; bFolder = false; nSubMtlSlot = -1; bUpdated = false; }

	void CreateItems();
	CMaterialBrowserRecord* GetParent() { return (CMaterialBrowserRecord*)GetParentRecord(); }
	void UpdateChildItems();
	CString CollectChildItems();

public:
	int nSubMtlSlot;
	CString materialName;
	uint32 materialNameCrc32;
	_smart_ptr<CMaterial> pMaterial;
	bool bFolder;
	bool bUpdated;
};
typedef std::vector<CMaterialBrowserRecord*> TMaterialBrowserRecords;

//////////////////////////////////////////////////////////////////////////
class CMaterialBrowserTreeCtrl : public CTreeCtrlReport
{
public:
	typedef CMaterialBrowserRecord CRecord;

public:
	CMaterialBrowserTreeCtrl();
	void SetMtlBrowser( CMaterialBrowserCtrl *pMtlBrowser ) { m_pMtlBrowser = pMtlBrowser; }
	
	static CRecord* RowToRecord( const CXTPReportRow *pRow )
	{
		if (pRow)
			return (CRecord*)pRow->GetRecord();
		return NULL;
	}

	//////////////////////////////////////////////////////////////////////////
	// Callbacks.
	//////////////////////////////////////////////////////////////////////////
	virtual void OnFillItems();
	virtual void OnSelectionChanged();
	virtual void OnItemExpanded( CXTPReportRow *pRow,bool bExpanded );
	virtual CTreeItemRecord* CreateGroupRecord( const CString &name,int nGroupIcon );

	//////////////////////////////////////////////////////////////////////////

	// Override from parent class
	virtual void DeleteAllItems();

	CRecord* GetItemForName( const CString &name );
	void SelectItem( CMaterialBrowserRecord *pRecord,const TMaterialBrowserRecords *pMarkedRecords );
	void UpdateItemState( CMaterialBrowserRecord *pItem );

	static int _cdecl RowCompareFunc(const CXTPReportRow** pRow1, const CXTPReportRow** pRow2);

protected:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnTreeKeyDown(NMHDR* pNMHDR, LRESULT* pResult);

protected:
	CMaterialBrowserCtrl* m_pMtlBrowser;
};

//////////////////////////////////////////////////////////////////////////
struct IMaterialBrowserListener
{
	virtual void OnBrowserSelectItem( IDataBaseItem* pItem,bool bForce ) = 0;
};



//////////////////////////////////////////////////////////////////////////
// CMaterialToolBar
//////////////////////////////////////////////////////////////////////////
class CMaterialToolBar : public CXTPToolBar
{
public:
	CMaterialToolBar();
	void Create(CWnd* pParentWnd);
	void Reset();

	// GetNewFilterText called in idle by user. If it returns true, outString is filled
	bool GetNewFilterText(CString& outString);

protected:
	BOOL OnCommand(WPARAM wParam, LPARAM lParam);

private:
	CXTPControlEdit* m_pEdit;

	CString m_filterText;
	float m_fIdleFilterTextTime;
};



//////////////////////////////////////////////////////////////////////////
// CMaterialBrowserCtrl
//////////////////////////////////////////////////////////////////////////
class CMaterialBrowserCtrl : public CToolbarDialog, public IDataBaseManagerListener, public IEditorNotifyListener
{
public:
	enum EViewType {
    VIEW_LEVEL = 0,
		VIEW_ALL = 1,
	};

	CMaterialBrowserCtrl();
	~CMaterialBrowserCtrl();

	enum { IDD = IDD_DATABASE };

	void SetListener( IMaterialBrowserListener *pListener ) { m_pListener = pListener; }
	BOOL Create( const RECT& rect,CWnd* pParentWnd,UINT nID );
	virtual CMaterialBrowserRecord* InsertItemToTree( IDataBaseItem *pItem,int nSubMtlSlot=-1,CMaterialBrowserRecord *pParentRecord=0 );

	void ReloadItems( EViewType viewType );
	EViewType GetViewType() const { return m_viewType; };

	void ClearItems();

	void AddItemToTree( IDataBaseItem *pItem,bool bUpdate );
	void SelectItem( IDataBaseItem *pItem );
	bool SelectItemByName( const CString materialName );
	void DeleteItem();
	
	void PopulateItems();

	bool ShowCheckedOutRecursive(CXTPReportRecords* pRecords);

	afx_msg void OnCopy();
	afx_msg void OnCopyName();
	afx_msg void OnPaste();
	afx_msg void OnCut();
	afx_msg void OnDuplicate();
	afx_msg void OnAddNewMaterial();
	afx_msg void OnAddNewMultiMaterial();
	afx_msg void OnMergeMaterials();
	afx_msg void OnReloadItems();
	afx_msg void OnShowCheckedOut();
	afx_msg void OnUpdateShowCheckedOut(CCmdUI *pCmdUI);
	bool CanPaste();
	void IdleSaveMaterial();

	void SetImageListCtrl( CMaterialImageListCtrl *pCtrl );

	//////////////////////////////////////////////////////////////////////////
	// IDataBaseManagerListener implementation.
	//////////////////////////////////////////////////////////////////////////
	virtual void OnDataBaseItemEvent( IDataBaseItem *pItem,EDataBaseItemEvent event );
	//////////////////////////////////////////////////////////////////////////

	virtual void OnEditorNotifyEvent( EEditorNotifyEvent event );

protected:
	// Item definition.
	enum ESourceControlOp
	{
		ESCM_GETPATH,
		ESCM_IMPORT,
		ESCM_CHECKIN,
		ESCM_CHECKOUT,
		ESCM_UNDO_CHECKOUT,
		ESCM_GETLATEST,
		ESCM_GETLATESTTEXTURES,
		ESCM_HISTORY,
	};

	void ReloadLevelItems();
	void ReloadAllItems();

	void ReloadTreeSubMtls( CMaterialBrowserRecord *pRecord,bool bForceCtrlUpdate=true );
	void RemoveItemFromTree( CMaterialBrowserRecord *pRecord );
	void DeleteItem( CMaterialBrowserRecord *pRecord );
	void SetSelectedItem( CMaterialBrowserRecord *pRecord,const TMaterialBrowserRecords *pMarkedRecords,bool bFromOnSelectOfCtrl );
	void OnAddSubMtl();
	void OnSelectAssignedObjects();
	void OnAssignMaterialToSelection();
	void OnRenameItem();
	void OnResetItem();
	void OnSetSubMtlCount( CMaterialBrowserRecord *pRecord );

	void DropToItem( CMaterialBrowserRecord *pTrgItem,CMaterialBrowserRecord *pSrcItem );

	int GetTexturesFromMaterial(CMaterial * pMat, CString & outPath);
	void DoSourceControlOp( CMaterialBrowserRecord *pRecord,ESourceControlOp );

	void OnMakeSubMtlSlot( CMaterialBrowserRecord *pRecord );
	void OnClearSubMtlSlot( CMaterialBrowserRecord *pRecord );
	void SetSubMaterial( CMaterialBrowserRecord *pRecord,int nSlot,CMaterial *pSubMaterial,bool bSelectSubMtl );

	void OnImageListCtrlSelect( struct CImageListCtrlItem *pItem );
	void OnSaveToFile( bool bMulti );

	void RefreshSelected();

	void TickRefreshMaterials();
	void TryLoadRecordMaterial( CMaterialBrowserRecord *pRecord );
	void LoadFromFiles( CFileUtil::FileArray &files );

	void ShowContextMenu( CMaterialBrowserRecord *pRecord,CPoint point );

	CMaterial* GetCurrentMaterial();

	uint32 MaterialNameToCrc32( const char *str );

	// Return record currently selected.
	CMaterialBrowserRecord* GetSelectedRecord();
	CString GetSelectedMaterialID();

	//////////////////////////////////////////////////////////////////////////
	// Messages.
	//////////////////////////////////////////////////////////////////////////
	DECLARE_MESSAGE_MAP()
	afx_msg void OnSize(UINT nType, int cx, int cy);
	//////////////////////////////////////////////////////////////////////////


private:
	friend class CMaterialBrowserTreeCtrl;

	CMaterialToolBar m_wndToolBar;
	CImageList m_imageList;

	CMaterialBrowserTreeCtrl m_tree;

	bool m_bIgnoreSelectionChange;
	bool m_bItemsValid;
	
	//CMaterialBrowserDlg m_browserDlg;
	CMaterialManager *m_pMatMan;
	IMaterialBrowserListener *m_pListener;
	CMaterialImageListCtrl *m_pMaterialImageListCtrl;

	EViewType m_viewType;
	bool m_bNeedReload;

	bool m_bHighlightMaterial;
	uint32 m_timeOfHighlight;

	typedef std::set<CMaterialBrowserRecord*> Items;
	Items m_items;

	CMaterialBrowserRecord *m_pCurrentRecord;
	TMaterialBrowserRecords m_markedRecords;

	CMaterial* m_pLastActiveMultiMaterial;

	float m_fIdleSaveMaterialTime;
	bool m_bShowOnlyCheckedOut;

	HCURSOR m_hCursorDefault;
	HCURSOR m_hCursorNoDrop;
	HCURSOR m_hCursorCreate;
	HCURSOR m_hCursorReplace;
};


/*
//////////////////////////////////////////////////////////////////////////
// CMaterialBrowserDlg
//////////////////////////////////////////////////////////////////////////
class CMaterialBrowserDlg : public CDialog
{
public:
	enum { IDD = IDD_MATERIAL_BROWSER };
	CMaterialBrowserDlg();
	~CMaterialBrowserDlg();

	void SetMtlBrowser( CMaterialBrowserCtrl *pMtlBrowser ) { m_pMtlBrowser = pMtlBrowser; }
	void SetListType( int type );

	BOOL OnInitDialog();

protected:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnRadioButton();
	afx_msg void OnReload();
	afx_msg void OnFilterChange();
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	virtual void OnOK() {};
	virtual void OnCancel() {};
	CEdit m_filterCtrl;
	CCustomButton m_reloadButton;
	int m_iSelection;
	CMaterialBrowserCtrl* m_pMtlBrowser;
};
*/



#endif // __MaterialBrowser_h__

